#!C:\Python25\python.exe

import SyntaxParser
import SQLGenerator
import SQLGenerator2
import conn
import condition
import answer
import patientCondition
import statistic
import Result
import Results
import cgi
import Diagnosis
from DatabaseConnector import leaves

print "Content-Type: text/html\n\n"
#print "<html><body>"
print """
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

<html>
	<head>
		<title>CDAL Results</title>
		<style type="text/css">
			body {
				font-family: Verdana, Tahoma, Sans-serif;
				font-size: 10pt;
			 	margin-top: 0;
			 	margin-left: 0;
			}
			
			div.title {
			 	float:right;
				font-weight:bold;
				margin-top: 18px;
				clear: left;
				padding-right: 20px;
				color:#FFFFFF;
				background-color: #39638B
			}
			
			#banner {
			 	margin-top: 0;
			 	margin-left: 0;
			 	background-image: url('/images/top_banner_in02.gif');
			 	background-position: 227px;
				background-repeat: no-repeat;
				background-color:#39638B; 
			}
			
			#title {
			 	font-family: Arial, Tahoma, Sans-serif;
			 	margin-top: 10px;
			 	margin-left: 5px;
			 	margin-bottom: 10px;
			 	font-weight: bold;
			 	font-size: 12pt;
			}
			
			#cdal {
				margin-left: 5px;
			}
			
			#cdal_title, #results_title {
				font-weight: bold;
				color: navy;
			}
			
			#cdal_content {
			 	margin-top: 5px;
			 	width: 600px;
			 	font-family: "courier new", mono;
			 	border-style: solid;
			 	border-width: 1px;
			 	border-color: grey;
			}
			
			#results {
			 	margin-left: 5px;
			 	margin-top: 5px;
			}
			
			div.stat_answer_required, div.ref_answer_required {
			 
			}
		
			div.stat_answer_content {
			 	font-size: 8pt;
			 	font-weight: normal;
			 	color: red;
			}
	
			table {
			 	border-collapse: collapse;
			}
			
			div.stat_answer_required, div.ref_answer_required {
			 	margin-top: 5px;
			}
			
			div.ref_answer_content {
			 	font-size: 8pt;
			 	margin-top: 5px;
			 	text-align: center;
			}
			
			div.generate_csv_file {
			 	margin-top: 5px;
			 	text-align: left;
			}

			td, th {
                            font-size: 8pt;
                        }
			
			#errors, #db_error, #answers_error, #global_time_period_error, #global_location_error, #demo_criterias_error, #diag_error, #med_criterias_error, #cdal_error {
			 	font-size: 8pt;
			 	font-weight: normal;
			 	color: red;
			}
			
			.cdal_error {
			 	font-size: 10pt;
			 	font-weight: normal;
			 	margin-left: 5px;
			 	color: red;
			}
			
			#link {
			 	float: right;
			 	margin-right: 5px;
			}
		</style>
	</head>
	
	<body>
		<div id='banner'>
			<div class='title'>
				Clinical Data Mining Project Group
			</div>
		  	<div> 
				<a href='http://www.usyd.edu.au'>
					 <img src='/images/top_banner_in01.gif' width='227' height='52' alt='The University of Sydney' style='border: 0px;' class='decor' /> 
				</a>
			</div>
		</div>
		<div id='link'>
			<a href='ht_interface.py'>Hypothesis testing</a>
		</div>
		<div id='title'>
			CDAL Results
		</div>
"""
# --------- dictionaries for archival database -----------

#path = 'D:\Victor\Elec\Elec4707\Source-Code-v2-1\doc/archive_patientevents_dictionary.txt'
path = 'doc/archive_patientevents_dictionary.txt'
archive_patientevents_dictionary = SyntaxParser.buildHash(path)

#path = 'D:\Victor\Elec\Elec4707\Source-Code-v2-1\doc/archive_chartevents_dictionary.txt'
path = 'doc/archive_chartevents_dictionary.txt'
archive_chartevents_dictionary = SyntaxParser.buildHash(path)

#path = 'D:\Victor\Elec\Elec4707\Source-Code-v2-1\doc/archive_medevents_dictionary.txt'
path = 'doc/archive_medevents_dictionary.txt'
archive_medevents_dictionary = SyntaxParser.buildHash(path)

path = 'doc/archive_labevents_dictionary.txt'
archive_labevents_dictionary = SyntaxParser.buildHash(path)

# --------- dictionaries for realtime database -----------

#path = 'D:\Victor\Elec\Elec4707\Source-Code-v2-2\doc/realtime_patientevents_dictionary.txt'
path = 'doc/realtime_patientevents_dictionary.txt'
realtime_patientevents_dictionary = SyntaxParser.buildHash(path)

#path = 'D:\Victor\Elec\Elec4707\Source-Code-v2-2\doc/realtime_chartevents_dictionary.txt'
path = 'doc/realtime_chartevents_dictionary.txt'
realtime_chartevents_dictionary = SyntaxParser.buildHash(path)

#path = 'D:\Victor\Elec\Elec4707\Source-Code-v2-2\doc/realtime_categoric_terms.txt'
path = 'doc/realtime_categoric_terms.txt'
categoric_terms = SyntaxParser.buildCategoricArray(path)

#path = 'D:\Victor\Elec\Elec4707\Source-Code-v2-2\doc/realtime_medevents_dictionary.txt'
path = 'doc/realtime_medevents_dictionary.txt'
realtime_medevents_dictionary = SyntaxParser.buildHash(path)

#path = 'D:\Victor\Elec\Elec4707\Source-Code-v2-2\doc/realtime_labevents_dictionary.txt'
path = 'doc/realtime_labevents_dictionary.txt'
realtime_labevents_dictionary = SyntaxParser.buildHash(path)

#added by Thomas Xie 23,May, 2008
path = 'doc/realtime_adtevents_dictionary.txt'
realtime_adtevents_dictionary = SyntaxParser.buildHash(path)

# --------- dictionaries shared by both databases -----------

path = 'doc/groupevents_dictionary.txt'
groupevents_dictionary = SyntaxParser.buildHash(path)

# ----------------added 25/9--------------------
path = 'doc/interface/dictionary.txt'
dictionary = SyntaxParser.buildHash(path)

path = 'doc/interface/patient_attributes.txt'
patient_attributes = SyntaxParser.buildHash(path)

path = 'doc/interface/toc_list.txt'
toc_array = SyntaxParser.buildArray(path)

path = 'doc/interface/databases.txt'
standard_databases = SyntaxParser.buildArray(path)

path = 'doc/interface/ref_entities.txt'
reference_entities = SyntaxParser.buildArray(path)

path = 'doc/interface/sta_entities.txt'
stat_entities = SyntaxParser.buildArray(path)

path = 'doc/interface/med_entities.txt'
medical_entities = SyntaxParser.buildHash(path)
#------------------------------------------------
# --------- definitions of CDAL -----------

comparands = [">",">=","<","<=","=","<>"]
types = ["and", "or"]
ref_fns = ["all values", "any value", "last value"] # yet to implement last value
stat_fns = ["mean", "sd", "median", "max", "min", "range", "mode", "sum", "count"] # yet to implement sum and count
time_entities = ["hours", "days", "weeks"]
keywords = [" whose ", " with ", " have ", " during ", " in "]

# --------- user query -----------

#answer = "all values of sedation"
#cond = ""
#patient = "mrn = 1390622" # mrn = 1390622
time_val = 60
time_ent = "hours"
#ward = 'GICU'
#showMRN = 0

# ----------------added 25/9------------------
toc = ''
db = ''
answer = ''
form = cgi.FieldStorage()
cdal = str(form.getvalue("cdal"))
cdal_error_array = []
patient = ''
cond = ''
diagnosis = ''
showMRN = 0
showMRNstring = str(form.getvalue("showMRN"))
if showMRNstring == 'on':
    showMRN = 1

#------------------STARTING SYNTAX CHECKING FOR CDAL---------------------------
#CHECKING TOC
current_start_index = 0
current_end_index = cdal.find(" ")
current_string = cdal[current_start_index:current_end_index].strip()
if current_string.upper() != 'USING':    
	error = 'Syntax Error in TOC: missing USING keyword'              
	cdal_error_array.append(error)
	
current_start_index = current_end_index
current_end_index = cdal.lower().find(" in ", current_start_index)

if current_end_index == -1:
	error = 'Syntax Error in DB: missing IN keyword'
	cdal_error_array.append(error)
else:
	current_string = cdal[current_start_index:current_end_index].strip()
	has_toc_ent = 0
	for toc_entity in toc_array:
		if current_string == toc_entity.upper():
			has_toc_ent = 1
			break
	if has_toc_ent == 0:
		error = 'Syntax Error in TOC: missing|incorrect TOC'
		print current_string
		cdal_error_array.append(error)
	else:
		#GETTING TOC
		toc = current_string
	
#CHECKING DATABASE
current_start_index = current_end_index + len(" in ")
current_end_index = cdal.lower().find(" find ", current_start_index)
if current_end_index == -1:
	error = 'Syntax error in ANSWERS: missing FIND keyword'
	cdal_error_array.append(error)
else:
	current_string = cdal[current_start_index:current_end_index].strip()
	has_db_ent = 0
	for standard_database in standard_databases:
		if current_string.upper() == standard_database.upper():
			has_db_ent = 1
			break
	if has_db_ent == 0:
		error = 'Syntax Error in DB: missing|incorrect database'
		cdal_error_array.append(error)
	else:
		#GETTING DB
		db = current_string
	
#CHECKING ANSWERS
current_start_index = current_end_index + len(" find ")
current_end_index = cdal.lower().find(" for patients ", current_start_index)
if current_end_index == -1:
	error = 'Syntax Error in ANSWERS: missing FOR PATIENTS keyword'
	cdal_error_array.append(error)
else:	
	current_string = cdal[current_start_index:current_end_index].strip()
	input_answers = []
	#GETTING THE ANSWER INPUT
	answer = current_string
	#CHECKING IF ANSWER IS VALID
	answers = current_string.lower().split(",")
	
	for input_answer in answers:
		has_ref_entity = 0
		has_sta_entity = 0
		has_med_entity = 0
		
		if input_answer.find(" of ") == -1:
			error = "Syntax Error in ANSWERS: Missing keyword 'OF'"
			cdal_error_array.append(error)
			break
		input_answer_tokens = input_answer.split(" of ")
		if len(input_answer_tokens) != 2:
			error = "Syntax Error in ANSWERS: Only 1 keyword 'OF' allowed in each answer"
			cdal_error_array.append(error)
			break
		
		input_fn_parts = input_answer_tokens[0].strip().lower().split(" and ")
		for input_fn in input_fn_parts:
			for reference_entity in reference_entities:
				if input_fn == reference_entity.lower():
					has_ref_entity = 1
					break
			if has_ref_entity == 0:
				for stat_entity in stat_entities:
					if input_fn == stat_entity.lower():
						has_sta_entity = 1
						break
				if has_sta_entity == 0:
					error = "Syntax Error in ANSWERS: Missing|Incorrect ref_ent|sta_ent"
					cdal_error_array.append(error)
					break
	
		if SyntaxParser.getTerm(input_answer_tokens[1].strip().lower(), medical_entities) == None:
			error = "Syntax Error in ANSWERS: Missing|Incorrect med_ent"
			cdal_error_array.append(error)
			break

has_diagnosis = 0
has_time_period = 0
has_location = 0

current_keyword = " for patients "
current_start_index = current_end_index + len(current_keyword)
current_end_index = cdal.find(" ", current_start_index)
current_string = cdal[current_start_index:current_end_index]
has_keyword = 0
for keyword in keywords:
	if current_string.lower().strip() == keyword.lower().strip():
		current_keyword = current_string
		has_keyword = 1
		break
if has_keyword == 0:
	error = "Syntax Error in CDAL: Missing keyword"
	cdal_error_array.append(error)
	
else:
	stop_signal = 0
	#CHECKING THE REST TOKENS OF CDAL
	#COULD BE DEMO CRITERIAS, MED CRITERIAS, DIAGNOSIS, TIME PERIOD OR LOCATION(WARD)
	while current_end_index != len(cdal):
		current_start_index = current_end_index
		current_end_index = SyntaxParser.getIndex(cdal, keywords, current_start_index)
		if current_end_index == -1:
			current_end_index = len(cdal)
			stop_signal = 1
		current_string = cdal[current_start_index:current_end_index]

		#CASE DEMO CRITERIAS
		if current_keyword.upper().strip() == 'WHOSE':
			if len(current_string.strip()) == 0:
				error = 'Syntax Error in DEMO CONDITIONS: missing demo conditions'
				cdal_error_array.append(error)
			else:
				patient = current_string.strip().lower()
				
		elif current_keyword.upper().strip() == 'WITH':
			if len(current_string.strip()) == 0:
				error = 'Syntax Error in MED CONDITIONS: missing med conditions'
				cdal_error_array.append(error)
			else:
				cond = current_string.strip().lower()
				
		elif current_keyword.upper().strip() == 'HAVE':
			has_diagnosis = 1
			index = current_string.lower().strip().find("diagnosis of ", 0)
			if index != 0:
			    error = 'Syntax Error in DIAGNOSIS: incomplete HAVE statement'
			    cdal_error_array.append(error)
			else:
			    diagnosis_ = current_string.strip()[12: len(current_string)]
			    if diagnosis_.strip() == '':
				error = 'Syntax Error in DIAGNOSIS: missing diagnosis information'
				cdal_error_array.append(error)
			    else:
				diagnosis = diagnosis_
		
		elif current_keyword.upper().strip() == 'DURING':
			has_time_period = 1
			index = current_string.lower().strip().find("the last ", 0)
			if index != 0:
				error = 'Syntax Error in TIME-PERIOD: incomplete DURING statement'
				cdal_error_array.append(error)
			else:
				global_time_period_ = current_string.strip()[9: len(current_string)]
				if global_time_period_.strip() == '':
					error = 'Syntax Error in TIME-PERIOD: missing TIME PERIOD'
					cdal_error_array.append(error)
				else:
					time_tokens = global_time_period_.split()
		
					if len(time_tokens) != 2:
						error = "Syntax error in TIME-PERIOD: Time should be in the format of [tim_val][tim_ent]"
						cdal_error_array.append(error)
					
					else:
						if time_tokens[0].strip().isdigit() != 1:
							error = "Syntax error in TIME-PERIOD: tim_val should be an integer"
							cdal_error_array.append(error)
						else:
							time_val = int(time_tokens[0])
							
						has_time_entity = 0
						for time_entity in time_entities:
							if time_tokens[1].strip().lower() == time_entity.lower():
								has_time_entity = 1
								break
						if has_time_entity == 0:
							error = "Syntax error in TIME-PERIOD: tim_ent should be in ['hours', 'days', 'weeks']"
							cdal_error_array.append(error)
						else:
							time_ent = time_tokens[1]
		
		elif current_keyword.upper().strip() == 'IN':
			has_location = 1
			if len(current_string.strip()) == 0:
				error = 'Syntax Error in LOCATION: missing location'
				cdal_error_array.append(error)
			else:
				ward = current_string.strip()
		
		if stop_signal == 1:
			break
			
		current_start_index = current_end_index
		current_end_index = cdal.find(" ", current_start_index + 1)
		current_keyword = cdal[current_start_index:current_end_index]

if has_time_period == 0:
	error = "Syntax Error in CDAL: missing time period"
	cdal_error_array.append(error)

if has_location == 0:
	error = "Syntax Error in CDAL: missing location"
	cdal_error_array.append(error)
	
# return the number of hrs of the query (so 1 day = 24 hrs)
duration = SyntaxParser.toHours(time_val, time_ent)

if duration <= 48:
	if has_diagnosis == 1:
		error = "Error: Diagnosis search for realtime database is currently not supported."
		cdal_error_array.append(error)

#-------------------------END SYNTAX CHECKING FOR CDAL---------------------------------
		
if len(cdal_error_array) > 0: # If there are errors
        for cdal_error in cdal_error_array:
			print "<div class='cdal_error'>" + cdal_error + "</div>"

else:

	# --------------------------------------------
	
	# ----------- Print CDAL entered -------------
	print """
		<div id='cdal'>
			<div id='cdal_title'>CDAL entered</div>
			<div id='cdal_content'>
	"""
	print cdal
	print """
			</div>
		</div>
	"""
	# --------- Start of all processes -----------
	
		
	results = Results.Results([],[],[])
	
	if has_diagnosis == 0:
		# if the time is <= 48 hrs, then consult realtime db only, o/w need connection to both dbs
		if duration > 48:
		    real_time_val = 48 # use in realtime
		else:
		    real_time_val = time_val
		
		# ----------- Start of realtime database queries --------------
		
		# Obtain the group-events component of the answer, if any (such as sedation, inotropes, etc)
		groupevents_answers = SyntaxParser.getAnswers(answer, ref_fns, stat_fns, groupevents_dictionary)
		
		# Obtain the chart-events component of the answer, if any (such as HR, Vent Mode, etc)
		chartevents_answers = SyntaxParser.getAnswers(answer, ref_fns, stat_fns, realtime_chartevents_dictionary)
		
		# Obtain the patient-events component of the answer, if any (such as mrn, fullname, etc)
		patientevents_answers = SyntaxParser.getAnswers(answer, ref_fns, stat_fns, realtime_patientevents_dictionary)
		
		# Obtain the med-events component of the answer, if any (such as any sedation and inotrope, etc)
		medevents_answers = SyntaxParser.getAnswers(answer, ref_fns, stat_fns, realtime_medevents_dictionary)
		
		# Obtain the lab-events component of the answer, if any (such as calcium, etc)
		labevents_answers = SyntaxParser.getAnswers(answer, ref_fns, stat_fns, realtime_labevents_dictionary)
		
		# Obtain the adt-events component of the answer, if any (such as admit time, bed number etc)
		adtevents_answers = SyntaxParser.getAnswers(answer, ref_fns, stat_fns, realtime_adtevents_dictionary)
		
		# Obtain the patient-events component of the conditions for the archival database, if any (such as mrn, fullname, etc)
		patient_conditions = SyntaxParser.getConditions(patient, comparands, types, realtime_patientevents_dictionary, 'T')
		patientevents_conditions = SyntaxParser.transform_Conditions(patient_conditions, "realtime")
		
		# Obtain the adt-events component of the conditions for the realtime database, if any (such as admit time,bed No.
		adtevents_conditions = SyntaxParser.getConditionArray(cond, comparands, types, realtime_adtevents_dictionary)

		# Obtain the chart-events component of the conditions, if any (such as HR, Vent Mode, etc)
		chartevents_conditions = SyntaxParser.getConditionArray(cond, comparands, types, realtime_chartevents_dictionary)
		
		# Obtain the med-events component of the conditions, if any (such as any sedation and inotrope, etc)
		medevents_conditions = SyntaxParser.getConditionArray(cond, comparands, types, realtime_medevents_dictionary)
		
		# Obtain the lab-events component of the conditions, if any (such as calcium, etc)
		labevents_conditions = SyntaxParser.getConditionArray(cond, comparands, types, realtime_labevents_dictionary)
		
		print "print:" 
		print groupevents_answers
		print patientevents_answers
		            
		# Generate the SQL Generator object, which is used to generate SQL queries for real-time database
                if showMRN == 1:
                    SQL = SQLGenerator.SQLGenerator('SNOMED','GICU',groupevents_answers,patientevents_answers,chartevents_answers,medevents_answers,labevents_answers, patientevents_conditions,chartevents_conditions,medevents_conditions, labevents_conditions, None, real_time_val, time_ent, ward, categoric_terms)
                else:
                    SQL = SQLGenerator2.SQLGenerator2('SNOMED','GICU',groupevents_answers,patientevents_answers,adtevents_answers,chartevents_answers,medevents_answers,labevents_answers, patientevents_conditions,adtevents_conditions, chartevents_conditions,medevents_conditions, labevents_conditions, None, real_time_val, time_ent, ward, categoric_terms)

		
		resultsArray = [] # array of results
		logicalArray = [] # array of logical operator
		
		result_set = [] # final set of results
		
		patients = None
		
		#append patients satisfying demographic info to the results array
		if patient_conditions is not None:
		    patientQuery = SQL.getPatientEvent()
		    patients = conn.toGICU(patientQuery)

#		if adtevents_conditions is not None:
#		    adteventsQuery = SQL.getAdtEvent()
#		    adtevents = conn.toGICU(adteventsQuery)
#		    
		for condition in adtevents_conditions:
		    logicalArray.append(condition.getType())
		    subQuery = SQL.generateSingleQuery(condition, "adtevents")
		    res = conn.toGICU(subQuery)
		    resultsArray.append(res)
		    		
		for condition in chartevents_conditions:
		    logicalArray.append(condition.getType())
		    subQuery = SQL.generateSingleQuery(condition, "chartevents")
		    res = conn.toGICU(subQuery)
		    resultsArray.append(res)
		
		for condition in medevents_conditions:
		    logicalArray.append(condition.getType())
		    subQuery = SQL.generateSingleQuery(condition, "medevents")
		    res = conn.toGICU(subQuery)
		    resultsArray.append(res)
		
		for condition in labevents_conditions:
		    logicalArray.append(condition.getType())
		    subQuery = SQL.generateSingleQuery(condition, "labevents")
		    res = conn.toGICU(subQuery)
		    resultsArray.append(res)
		
		# Get the final group of patients whose conditions are satisfied
		finalResultArray = SyntaxParser.getFinalResult(patients, resultsArray, logicalArray)
		
		cont = 1
		if finalResultArray is None:
			# if none, then there is no conditions, so retrieve all records in db
			cont = 1
			
		elif len(finalResultArray) == 0:
			# if length = 0, then there is no patient that satisfy all condition,s so retur nothing
			cont = -1
		
		if cont == 1:
			for ind in range(0,len(groupevents_answers)):
			    query_realtime = SQL.generateFinalQuery("groupevents", finalResultArray, ind)
                            #print query_realtime
                            res_realtime = conn.toGICU(query_realtime,4)
			
			    # creating a Result Object
			    result = Result.Result(groupevents_answers[ind].getVariable(),"groupevents",res_realtime,groupevents_answers[ind].getStat_fn(),groupevents_answers[ind].getRef_fn())
			
			    # Append Result object to Results
			    results.AppendRealtime(result)
			
			for ind in range(0,len(patientevents_answers)):
			    query_realtime = SQL.generateFinalQuery("patientevents", finalResultArray, ind)
                            #print query_realtime
			    res_realtime = conn.toGICU(query_realtime)
			
			    # creating a Result Object
			    result = Result.Result(patientevents_answers[ind].getVariable(),"patientevents",res_realtime,patientevents_answers[ind].getStat_fn(),patientevents_answers[ind].getRef_fn())
			
			    # Append Result object to Results
			    results.AppendRealtime(result)
			    
			for ind in range(0,len(adtevents_answers)):
			    query_realtime = SQL.generateFinalQuery("adtevents", finalResultArray, ind)
                            #print query_realtime
			    res_realtime = conn.toGICU(query_realtime)
			
			    # creating a Result Object
			    result = Result.Result(adtevents_answers[ind].getVariable(),"adtevents",res_realtime,adtevents_answers[ind].getStat_fn(),adtevents_answers[ind].getRef_fn())
			
			    # Append Result object to Results
			    results.AppendRealtime(result)			    
			
			for ind in range(0,len(chartevents_answers)):
			    query_realtime = SQL.generateFinalQuery("chartevents", finalResultArray, ind)
                            #print query_realtime
			    res_realtime = conn.toGICU(query_realtime,3)
			
			    # creating a Result Object
			    result = Result.Result(chartevents_answers[ind].getVariable(),"chartevents",res_realtime,chartevents_answers[ind].getStat_fn(),chartevents_answers[ind].getRef_fn())
			
			    # Append Result object to Results
			    results.AppendRealtime(result)
			
			for ind in range(0,len(medevents_answers)):
			    query_realtime = SQL.generateFinalQuery("medevents", finalResultArray, ind)
                            #print query_realtime
			    res_realtime = conn.toGICU(query_realtime,3)
			
			    # creating a Result Object
			    result = Result.Result(medevents_answers[ind].getVariable(),"medevents",res_realtime,medevents_answers[ind].getStat_fn(),medevents_answers[ind].getRef_fn())
			
			    # Append Result object to Results
			    results.AppendRealtime(result)
			
			for ind in range(0,len(labevents_answers)):
			    query_realtime = SQL.generateFinalQuery("labevents", finalResultArray, ind)
                            #print query_realtime
			    res_realtime = conn.toGICU(query_realtime,3)
			    
			    # creating a Result Object
			    result = Result.Result(labevents_answers[ind].getVariable(),"labevents",res_realtime,labevents_answers[ind].getStat_fn(),labevents_answers[ind].getRef_fn())
			
			    # Append Result object to Results
			    results.AppendRealtime(result)        
	
		# ----------- End of realtime database queries --------------
	
	# ----------- Start of archival database queries (if required) --------------
	
	if duration > 48:
	    diagnosis_object = Diagnosis.Diagnosis(diagnosis)
	    diagnosis_pid_array = diagnosis_object.getDiagnosisPidArray()
	
	    # Obtain the group-events component of the answer, if any (such as sedation, inotropes, etc)
	    groupevents_answers = SyntaxParser.getAnswers(answer, ref_fns, stat_fns, groupevents_dictionary)
	
	    # Obtain the chart-events component of the answer, if any (such as HR, Vent Mode, etc)
	    chartevents_answers = SyntaxParser.getAnswers(answer, ref_fns, stat_fns, archive_chartevents_dictionary)
	
	    # Obtain the patient-events component of the answer, if any (such as mrn, fullname, etc)
	    patientevents_answers = SyntaxParser.getAnswers(answer, ref_fns, stat_fns, archive_patientevents_dictionary)
	
	    # Obtain the med-events component of the answer, if any (such as any sedation and inotrope, etc)
	    medevents_answers = SyntaxParser.getAnswers(answer, ref_fns, stat_fns, archive_medevents_dictionary)
	
	    # Obtain the lab-events component of the answer, if any (such as calcium, etc)
	    labevents_answers = SyntaxParser.getAnswers(answer, ref_fns, stat_fns, archive_labevents_dictionary)
	
	    # Obtain the patient-events component of the conditions for the archival database, if any (such as mrn, fullname, etc)
	    patient_conditions = SyntaxParser.getConditions(patient, comparands, types, archive_patientevents_dictionary, 'T')
	    patientevents_conditions = SyntaxParser.transform_Conditions(patient_conditions, "archive")
	
	    # Obtain the chart-events component of the conditions, if any (such as HR, Vent Mode, etc)
	    chartevents_conditions = SyntaxParser.getConditions(cond, comparands, types, archive_chartevents_dictionary)
	
	    # Obtain the med-events component of the conditions, if any (such as any sedation and inotrope, etc)
	    medevents_conditions = SyntaxParser.getConditions(cond, comparands, types, archive_medevents_dictionary)
	
	    # Obtain the lab-events component of the conditions, if any (such as calcium, etc)
	    labevents_conditions = SyntaxParser.getConditions(cond, comparands, types, archive_labevents_dictionary)
	
	    # Generate the SQL Generator object, which is used to generate SQL queries for both real-time and archival databases
            if showMRN == 1:
                SQL = SQLGenerator.SQLGenerator(toc,db,groupevents_answers,patientevents_answers,chartevents_answers,medevents_answers,labevents_answers, patientevents_conditions,chartevents_conditions,medevents_conditions,labevents_conditions, diagnosis_pid_array, time_val,time_ent,ward, None)
            else:
                SQL = SQLGenerator2.SQLGenerator2(toc,db,groupevents_answers,patientevents_answers,chartevents_answers,medevents_answers,labevents_answers, patientevents_conditions,chartevents_conditions,medevents_conditions,labevents_conditions, diagnosis_pid_array, time_val,time_ent,ward, None)

	    result_set = [] # final set of results
	
	    # Here, we split each SQL into 2 halves. The 1st half ('<') contains pid up to 10000, the 2nd ('>=') from 10000 onwards.
	    # The rationale behind this is to speed up the overall query
	    # There are 4 variables to retrieve for every group_events (mrn, label, value, chart-time)
	    # There are only 1 variable to retrieve for all other events (value)
	    for ind in range(0,len(groupevents_answers)):
	        query_archive = SQL.generateArchiveSQL("groupevents", ind, "<")
	        #print query_archive
	        if query_archive == -1:
                    break

	        res_archive1 = conn.toISM(query_archive,4) # 4 variables to retrieve
	        
	        query_archive = SQL.generateArchiveSQL("groupevents", ind, ">=")
	        
	        res_archive2 = conn.toISM(query_archive,4)
	
	        # combine the results for the 2 sets
	        res_archive = SyntaxParser.joinResults(res_archive1, res_archive2)
	
	        # creating a Result Object
	        result = Result.Result(groupevents_answers[ind].getVariable(),"groupevents",res_archive,groupevents_answers[ind].getStat_fn(),groupevents_answers[ind].getRef_fn())
	
	        # Append Result object to Results
	        results.AppendArchive(result)
	
	    for ind in range(0,len(chartevents_answers)):
	        query_archive = SQL.generateArchiveSQL("chartevents", ind, "<")
	        #print query_archive
	        if query_archive == -1:
                    break

                res_archive1 = conn.toISM(query_archive, 3) # 3 variable to retrieve
                
	        query_archive = SQL.generateArchiveSQL("chartevents", ind, ">=")
	        if query_archive == -1:
                    break
	        
                res_archive2 = conn.toISM(query_archive, 3) # 3 variable to retrieve
	
	        # combine the results for the 2 sets
	        res_archive = SyntaxParser.joinResults(res_archive1, res_archive2)
	
	        # creating a Result Object
	        result = Result.Result(chartevents_answers[ind].getVariable(),"chartevents",res_archive,chartevents_answers[ind].getStat_fn(),chartevents_answers[ind].getRef_fn())
	
	        # Append Result object to Results
	        results.AppendArchive(result)
	
	    for ind in range(0,len(patientevents_answers)):
	        query_archive = SQL.generateArchiveSQL("patientevents", ind, "<")
	        #print query_archive
	        if query_archive == -1:
                    break
	        
	        res_archive1 = conn.toISM(query_archive)
                
	        query_archive = SQL.generateArchiveSQL("patientevents", ind, ">=")
	        if query_archive == -1:
                    break
                
	        res_archive2 = conn.toISM(query_archive)
	
	        # combine the results for the 2 sets
	        res_archive = SyntaxParser.joinResults(res_archive1, res_archive2)
	
	        # creating a Result Object
	        result = Result.Result(patientevents_answers[ind].getVariable(),"patientevents",res_archive,patientevents_answers[ind].getStat_fn(),patientevents_answers[ind].getRef_fn())
	
	        # Append Result object to Results
	        results.AppendArchive(result)
	
	    for ind in range(0,len(medevents_answers)):
	        query_archive = SQL.generateArchiveSQL("medevents", ind, "<")
	        #print query_archive
	        if query_archive == -1:
                    break

	        res_archive1 = conn.toISM(query_archive, 3) # 3 variable to retrieve
                
	        query_archive = SQL.generateArchiveSQL("medevents", ind, ">=")
	        if query_archive == -1:
                    break

                res_archive2 = conn.toISM(query_archive, 3) # 3 variable to retrieve
	
	        # combine the results for the 2 sets
	        res_archive = SyntaxParser.joinResults(res_archive1, res_archive2)
	
	        # creating a Result Object
	        result = Result.Result(medevents_answers[ind].getVariable(),"medevents",res_archive,medevents_answers[ind].getStat_fn(),medevents_answers[ind].getRef_fn())
	
	        # Append Result object to Results
	        results.AppendArchive(result)
	
	    for ind in range(0,len(labevents_answers)):
	        query_archive = SQL.generateArchiveSQL("labevents", ind, "<")
	        #print query_archive
	        if query_archive == -1:
                    break
	        
                res_archive1 = conn.toISM(query_archive, 3) # 3 variable to retrieve
                
	        query_archive = SQL.generateArchiveSQL("labevents", ind, ">=")
	        if query_archive == -1:
                    break
                
                res_archive2 = conn.toISM(query_archive, 3) # 3 variable to retrieve
	
	        # combine the results for the 2 sets
	        res_archive = SyntaxParser.joinResults(res_archive1, res_archive2)
	
	        # creating a Result Object
	        result = Result.Result(labevents_answers[ind].getVariable(),"labevents",res_archive,labevents_answers[ind].getStat_fn(),labevents_answers[ind].getRef_fn())
	
	        # Append Result object to Results
	        results.AppendArchive(result)
	
	# ----------- End of archival database queries --------------
	
	# Combining the realtime and the archival results together to generate final result
	if has_diagnosis == 1:
            results.setFinalResult(results.getArchiveResult())
	elif duration > 48:
	    realtime_result = results.getRealtimeResult()
	    archive_result = results.getArchiveResult()
	    for real_res in realtime_result:
	        real_att = real_res.getAttribute()
	        for arch_res in archive_result:
	            arch_att = arch_res.getAttribute()
	            
		    if real_att == 'medrecnum':
                	real_att = 'mrn'
	            
		    if real_att == arch_att:
	                real_values = real_res.getValues()
	                archive_values = arch_res.getValues()
	
	                # Join the results from both realtime and archive databases together
	                res_joined = SyntaxParser.joinResults(archive_values, real_values)
	
	                # creating a Result Object
	                result = Result.Result(real_att, real_res.getEventType(), res_joined, real_res.getStatEnt(), real_res.getRefEnt())
	
	                # Append Result object to Results
	                results.AppendFinal(result)
	
	                break
	else:
	    results.setFinalResult(results.getRealtimeResult())
	
	# ----------- End of all processes --------------
	
	# show all the reference entity (all values) and statistical entity (mean, sd) for all events on answers for both databases
	
	print "<div id='results'>"
	print "<div id='results_title'>Results (Retrieved at " + str(SyntaxParser.getCurrentTime()) + ")</div>"
	
        final_result = results.getFinalResult()
        if len(final_result) == 0:
		print "No result generated..."
	else:
	        for res in final_result:
	            var = res.getAttribute()
	            values = res.getValues()
	            res_type = res.getEventType()
	            stat_array = res.getStatEnt()
	            ref_array = res.getRefEnt()
	            if len(values) > 0:
	                if stat_array is not None:
	                    for stat in stat_array:
                                if res_type == "groupevents":
                                    numeric_values = SyntaxParser.getValues(values,2)
                                else:
                                    numeric_values = SyntaxParser.getValues(values)
                                    
	                        if stat == "mean":
	                            print "<div class='stat_answer_required'><i>Mean of " + var + ":</i></div>"
	                            print "<div class='stat_answer_content'>" + str(statistic.mean(numeric_values)) + "</div>"
	                        elif stat == "sd":
	                            print "<div class='stat_answer_required'><i>SD of " + var + ":</i></div>"
	                            print "<div class='stat_answer_content'>" + str(statistic.s_d(numeric_values)) + "</div>"
	                        elif stat == "median":
	                            print "<div class='stat_answer_required'><i>Median of " + var + ":</i></div>"
	                            print "<div class='stat_answer_content'>" + str(statistic.median(numeric_values)) + "</div>"
	                        elif stat == "max":
	                            print "<div class='stat_answer_required'><i>Max of " + var + ":</i></div>"
	                            print "<div class='stat_answer_content'>" + str(statistic.maximum(numeric_values)) + "</div>"
	                        elif stat == "min":
	                            print "<div class='stat_answer_required'><i>Min of " + var + ":</i></div>"
	                            print "<div class='stat_answer_content'>" + str(statistic.minimum(numeric_values)) + "</div>"
	                        elif stat == "count":
	                            print "<div class='stat_answer_required'><i>Count of " + var + ":</i></div>"
	                            print "<div class='stat_answer_content'>" + str(statistic.count(numeric_values)) + "</div>"
	                if ref_array is not None:
	                    for ref in ref_array:
	                        if ref == "all values":   
	                            print "<div class='ref_answer_required'><i>All values of " + var + ": (" + str(len(values)) + " results retrieved)</i></div>"
	                            print "<div class='ref_answer_content'>"
	                            print "<table border='1'>"
	                            if res_type == 'patientevents':
	                                print "<tr><th>" + var + "</th></tr>"
	                                for rs in values:
	                                    print "<tr><td style='color:red'>" + str(rs) + "</td></tr>"
	                            
	                            elif res_type == 'groupevents' and showMRN == 1:
	                                print "<tr><th>MRN</th><th>" + var + "</th><th>Value</th><th>Time</th></tr>"
	                                for rs in values:
	                                    rs_tokens = rs.split(';')
	                                    if len(rs_tokens) != 4:
	                                        print "<tr><td colspan='4'>" + str(rs) + "</td></tr>"
	                                    else:
	                                        this_mrn = rs_tokens[0]
	                                        this_var = rs_tokens[1]
	                                        this_val = rs_tokens[2]
	                                        this_tim = rs_tokens[3]
	                                        if this_val == "None":
                                                    this_val = "!Chart"
	                                        print "<tr><td>" + this_mrn + "</td><td>" + this_var + "</td><td style='color:red'>" + this_val + "</td><td>" + this_tim + "</td></tr>"
                                    elif res_type == 'groupevents' and showMRN == 0:
	                                print "<tr><th>ID</th><th>" + var + "</th><th>Value</th><th>Time</th></tr>"
	                                for rs in values:
	                                    rs_tokens = rs.split(';')
	                                    if len(rs_tokens) != 4:
	                                        print "<tr><td colspan='4'>" + str(rs) + "</td></tr>"
	                                    else:
	                                        this_mrn = rs_tokens[0]
	                                        this_var = rs_tokens[1]
	                                        this_val = rs_tokens[2]
	                                        this_tim = rs_tokens[3]
	                                        if this_val == "None":
                                                    this_val = "!Chart"
	                                        print "<tr><td>" + this_mrn + "</td><td>" + this_var + "</td><td style='color:red'>" + this_val + "</td><td>" + this_tim + "</td></tr>"

	                            elif showMRN == 0:
                                        print "<tr><th>ID</th><th>Time</th><th>Value</th></tr>"
	                                for rs in values:
	                                    rs_tokens = rs.split(";")
	                                    if len(rs_tokens) != 3:
	                                        print "<tr><td colspan='3'>" + str(rs) + "</td></tr>"
	                                    else:
	                                        this_mrn = rs_tokens[0]
	                                        this_tim = rs_tokens[2]
	                                        this_val = rs_tokens[1]
	                                        if this_val == "None":
                                                    this_val = "!Chart"
	                                        print "<tr><td>" + this_mrn + "</td><td>" + this_tim + "</td><td style='color:red'>" + this_val + "</td></tr>"
	                            
	                            else:
	                                print "<tr><th>MRN</th><th>Time</th><th>Value</th></tr>"
	                                for rs in values:
	                                    rs_tokens = rs.split(";")
	                                    if len(rs_tokens) != 3:
	                                        print "<tr><td colspan='3'>" + str(rs) + "</td></tr>"
	                                    else:
	                                        this_mrn = rs_tokens[0]
	                                        this_tim = rs_tokens[2]
	                                        this_val = rs_tokens[1]
	                                        if this_val == "None":
                                                    this_val = "!Chart"
	                                        print "<tr><td>" + this_mrn + "</td><td>" + this_tim + "</td><td style='color:red'>" + this_val + "</td></tr>"
	                            
	                            print "</table>"
	                            print "</div>" #Closing div 'ref_answer_content'
                                                    
	            else:
	                print "no value of " + var + " is found."
                
        print "</div>" #Closing div 'Results'
print "</body></html>"
